import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import { requestUserLogin, requestUserInfo, requestLoginOut } from "@/api/userInfo"
import type { requestUserInfoReturn, loginParamsType } from "@/api/userInfo"
import type { RouteRecordRaw } from "vue-router"
import { staticRoutes, allAsyncRoutes, anyRoute } from '@/router/routes'
import cloneDeep from "lodash/cloneDeep";
import router from '@/router';

// 根据用户信息过滤动态路由
function filterAsyncRoutes(allAsyncRoutes: RouteRecordRaw[], routerNames: string[]) {
  return allAsyncRoutes.filter(item => {
    if (routerNames.includes(item.name as string)) {
      if (item.children && item.children.length) {
        item.children = filterAsyncRoutes(item.children as unknown as RouteRecordRaw[], routerNames)
      }
      return true
    }
  })
}

// 将由用户信息过滤出来的动态路由以及任意路由插入到已经注册的路由器上
function addRoutes(routes: RouteRecordRaw[]) {
  routes.forEach(item => {
    router.addRoute(item)
  })
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */

export interface UserInfoState {
  token: string,
  userInfo: requestUserInfoReturn,
  menuRoutes: RouteRecordRaw[]
}
export const useUserInfoStore = defineStore('userInfo', {

  state: (): UserInfoState => ({
    token: (getToken() as string) || '',
    userInfo: {
      routes: [],
      buttons: [],
      roles: [],
      name: "",
      avatar: ""
    },
    menuRoutes: staticRoutes
  }),

  actions: {
    async login(loginParams: loginParamsType) {
      try {
        // 发送登录请求
        const result = await requestUserLogin(loginParams)
        // 将token设置给state
        this.token = result.token
        // 将token设置到localStorage中做自动登录
        setToken(this.token)
      } catch (e) {
        return Promise.reject(e)
      }
    },

    // 用户信息请求
    async getInfo() {
      try {
        // 发送用户信息请求
        const result = await requestUserInfo()

        // 将数据交给state
        this.userInfo = result

        // 获取用户信息后根据数据过滤出来需要的动态路由
        const userAsyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes), result.routes)
        // 将需要的动态路由和任意路由插入到路由器中
        addRoutes(userAsyncRoutes.concat(anyRoute))
        // 修改静态路由
        this.menuRoutes = staticRoutes.concat(userAsyncRoutes, anyRoute)
      } catch (e) {
        return Promise.reject(e)
      }
    },

    // 用户登出请求
    async getLogout() {
      try {
        // 发出登出请求
        await requestLoginOut()
        // 执行清理操作
        this.reset()

        // 退出登录的时候将路由器中的路由全部清理掉
        // 获取所有的路由
        const routes = router.getRoutes()
        routes.forEach(item => {
          if (item.name) {
            router.removeRoute(item.name)
          }
        })
        // 清理完后再将静态路由插入到路由器中
        addRoutes(staticRoutes)
      } catch (e) {
        return Promise.reject(e)
      }
    },

    // 清理操作
    reset() {
      // 删除local中保存的token
      removeToken()
      // 提交重置用户信息的mutation
      this.token = ''
      this.userInfo = {
        routes: [],
        buttons: [],
        roles: [],
        name: "",
        avatar: ""
      }
    },
  },
});
